Amazon Linux 2023上にRustのWindows向けクロスコンパイル環境を作ってみた
初めに
以前CodeBuildのLinuxコンテナ上でWindows向けにクロスコンパイルする環境を作成しました。
上記記事ではAmazon Linuxベースのコンテナで解決できずUbuntuを利用しましたが、せっかくなのでAmazon Linux 2023のパターンでも作れる環境パターンを見てみたいなと思い試してみました。
(Amazon Linux 2の場合はamazon-linux-extrasからepelが導入可能で記載の手順で環境作成可能です)
なお今回はAmazon Linux 2023ベースのコンテナではなくAmazon Linux 2023を利用したEC2上での作業を行いますが、似たような処理を書き込めばコンテナ環境でも再現できるとは考えてます。
対応方法
Windows向けにクロスコンパイルするためにはcargo init
で生成されたHello Worldのプログラムでも最低限mingw64-gcc
,mingw-64-winpthreads-static
が必要となります。
残念ながらこれらのパッケージは2022/05/19時点(まだAmazon Linux 2022だった頃)の標準リポジトリには含まれていたのですが、2022/05/31のアップデート時点で消滅しており現在も再追加は行われていません。
この時点では含まれていた。
次のリリースノートでは消えていた。
https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/relationship-to-fedora.html
The Generally Available (GA) version of AL2023 isn't directly comparable to any specific Fedora release. The AL2023 GA version includes components from Fedora 34, 35, and 36. Some of the components are the same as the components in Fedora and some are modified. Other components more closely resemble the components in CentOS 9 Streams or were developed independently. The Amazon Linux kernel is sourced from the long-term support options that are on kernel.org, chosen independently from Fedora.
ドキュメントを探してみるとAmazon Linux 2023はFedora 34~36やFedora34がベースとなっているCentOS Stream 9のコンポーネントが元となっているようです。
確認してみたところFedora 34の標準リポジトリにMinGW関連のパッケージは含まれているのでこちらか必要なパッケージを取得することで対応ができそうです。
注意点としてAmazon Linux 2023は完全にFedoraやCentOS Streamと同一ではなく動作が保証されるわけではないので予期せぬ動作を引き起こす可能性がある点を十分理解した上で自己責任で使う必要があります。
当然AWSからのサポートもないのでルール的にどうしてもAmazon Linux系以外が使えないという条件がなければ別のOSを選択するか、EOLが切れるまでであればAmazon Linux 2で対応するのが無難な選択肢とは思います。
設定
rpmを直接取得しインストールしてもいいですが依存関係の自力解決の手間なのでFedora 34のリポジトリからyum経由で取得できるようにします。
/etc/yum.repo.d/
配下にfedora34.repo
ファイルを作成します。
設定値はDockerでfedora:34
のコンテナを実行しそちらを参考に作成しています。
[fedora34] name=Fedora 34 - $basearch #baseurl=http://download.example/pub/fedora/linux/releases/$releasever/Everything/$basearch/os/ metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-34&arch=$basearch enabled=1 countme=1 metadata_expire=7d repo_gpgcheck=0 type=rpm gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-34-$basearch skip_if_unavailable=False [fedora34-updates] name=Fedora 34 - $basearch - Updates #baseurl=http://download.example/pub/fedora/linux/updates/$releasever/Everything/$basearch/ metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f34&arch=$basearch enabled=1 countme=1 repo_gpgcheck=0 type=rpm gpgcheck=1 metadata_expire=6h gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-34-$basearch skip_if_unavailable=False
gpg鍵は以下より取得し配置しました。
fedora34
側の設定だけ追加してなぜかNo packagesになる!と少しだけハマりましたがupdates
の方に含まれるようです。
# 手元のMAC環境のfedora:34条の実行結果(ARMプロセッサのためaarch64になっています) $ yum install mingw64-gcc Last metadata expiration check: 0:00:30 ago on Thu Jul 20 07:17:47 2023. Dependencies resolved. ============================================================================================================================================================================================================================================== Package Architecture Version Repository Size ============================================================================================================================================================================================================================================== Installing: mingw64-gcc aarch64 10.3.1-2.fc34 updates 20 M Installing dependencies: dwz aarch64 0.14-1.fc34 fedora 126 k efi-srpm-macros noarch 5-4.fc34 updates 22 k file aarch64 5.39-7.fc34 updates 50 k findutils aarch64 1:4.8.0-2.fc34 fedora 547 k fonts-srpm-macros noarch 1:2.0.5-5.fc34 fedora 27 k fpc-srpm-macros noarch 1.3-3.fc34 fedora 7.7 k
インストール
ここまで来たらあとは追加したリポジトリを利用してyum(dnf)でインストールするだけです。
$ sudo yum install -y mingw64-{gcc,winpthreads-static} --enablerepo=fedora34{,-updates} Last metadata expiration check: 0:01:48 ago on Thu Jul 20 07:36:53 2023. Dependencies resolved. ============================================================================================================================================================================== Package Architecture Version Repository Size ============================================================================================================================================================================== Installing: mingw64-gcc x86_64 10.3.1-2.fc34 fedora34-updates 20 M mingw64-winpthreads-static noarch 8.0.0-2.fc34 fedora34 31 k Installing dependencies: isl x86_64 0.16.1-13.amzn2023.0.3 amazonlinux 872 k mingw-binutils-generic x86_64 2.34-11.fc34 fedora34-updates 1.0 M mingw-filesystem-base noarch 118-1.fc34 fedora34-updates 20 k mingw64-binutils x86_64 2.34-11.fc34 fedora34-updates 2.4 M mingw64-cpp x86_64 10.3.1-2.fc34 fedora34-updates 8.3 M mingw64-crt noarch 8.0.0-2.fc34 fedora34 2.7 M mingw64-filesystem noarch 118-1.fc34 fedora34-updates 152 k mingw64-headers noarch 8.0.0-2.fc34 fedora34 4.9 M mingw64-winpthreads noarch 8.0.0-2.fc34 fedora34 48 k Transaction Summary ============================================================================================================================================================================== Install 11 Packages ...
Rust側の環境もセットアップしておきます。
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y ... $ source $HOME/.cargo/env $ rustup target add x86_64-pc-windows-gnu ...
コンパイル
cargo init
でサンプルプロジェクトを作りその中でx86_64-pc-windows-gnu
向けにコンパイルを行ったところ無事Windows向けのバイナリが生成されていることを確認できました。
$ mkdir sample-rust-prj && cd sample-rust-prj && cargo init Created binary (application) package $ cargo build --release --target x86_64-pc-windows-gnu Compiling sample-rust-prj v0.1.0 (/root/sample-rust-prj) Finished release [optimized] target(s) in 0.81s # Windows向けバイナリなのでLinux上で実行すると当然失敗する $ cargo run --release --target x86_64-pc-windows-gnu Finished release [optimized] target(s) in 0.00s Running `target/x86_64-pc-windows-gnu/release/sample-rust-prj.exe` target/x86_64-pc-windows-gnu/release/sample-rust-prj.exe: target/x86_64-pc-windows-gnu/release/sample-rust-prj.exe: cannot execute binary file
終わりに
Amazon Linux 2023になってからEPELも利用できず標準リポジトリからもMinGW関連のパッケージが消えてしまっている状態ですが、なんとか入れ込んでWindows向けのクロスコンパイル環境を作ることができました。
まだAmazon Linux 2がEOL未到来のためそちらを使い続けることは可能ですが、到来までに何かしらの対応がない場合は今回のような方法を取るか別のOSを選択する形になってくるのではないかと思います。
今回はFedoraのリポジトリからパッケージを取得しインストールしていますが、Amazon Linux 2023はあくまで近いものであり同一ではない関係で動作は保証されるものではないですし、なんらか不具合が出る可能性も考慮すると決してリスクが低いと言えるものではないためもし利用する方はそれを踏まえた上で自己責任にて利用いただくようにご注意ください。